//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "circuloEspiral.h"

//---------------------------------------------------------------------------

#pragma package(smart_init)
CirculoEspiral::CirculoEspiral(int s, int q, int r){
        np=s;
        Lista<PV> * iniciales=new Lista<PV>();
        nq=q;

        radio=r;
        this->setNv(0);
        this->setNc(0);
        this->setNn(0);

        Cara * c1,*c2;
        VerticeNormal *v;
        double t=0,tgrad;
        //primera circunferencia (poligono regular de np lados)
        //vertices auxiliares para hacer la transformacion
                PV * p;
                for (int i= 0; i < np; i++){
                   p = new PV(radio * cos(2 * M_PI * i/np),
                              radio * sin(2 * M_PI * i/np),
                               0,1);
                   iniciales->anadir(p);
                  // this->setNv( this->getNv() + 1);
                }
                t=0;
                tgrad=0;
                PV * anterior;
        //primera circunferencia de la espiral
                for (int i= 0; i < np; i++){
                  anterior=iniciales->dameDato((i+1));
                  p=  new PV(-sin(t)*anterior->getX()+cos(t)*anterior->getZ()+cos(t)+tgrad*sin(t),
                              -anterior->getY(),
                              cos(t)*anterior->getX()+sin(t)*anterior->getZ()+sin(t)-tgrad*cos(t),anterior->getV());


                   this->getVertice()->anadir(p);
                   this->setNv( this->getNv() + 1);
                }


             //cara


        //Laterales de la espiral

         for(int j=0;j<nq;j++){
                t=  -5* M_PI * (j)/(nq+1);

                tgrad=t*180/M_PI;


             //siguiente circunferencia
                for (int i= 0; i < np; i++){
                  anterior=iniciales->dameDato((i+1));
                  p=  new PV(-sin(t)*anterior->getX()+cos(t)*anterior->getZ()+cos(t)+tgrad*sin(t),
                              -anterior->getY(),
                              cos(t)*anterior->getX()+sin(t)*anterior->getZ()+sin(t)-tgrad*cos(t),anterior->getV());


                   this->getVertice()->anadir(p);
                   this->setNv( this->getNv() + 1);
                }
             //normales

                for (int i= 1; i <= np; i++){
                   PV * p1,* p2, * v1, * v2;
                   p1=this->getVertice()->dameDato(i+np*j);
                   p2=this->getVertice()->dameDato((i%np)+j*np+1);
                   v1=new PV(0,0,0,0);
                   v1->vectorDosPV(p1,p2);
                   v1->normalizacion();
                   p2=this->getVertice()->dameDato(i+np+np*j);
                   v2=new PV(0,0,0,0);
                   v2->vectorDosPV(p1,p2);
                   v2->normalizacion();
                   p=v1->producto_vectorial(v1,v2);
                   
                   p->normalizacion();
                   delete v1;
                   delete v2;
                   this->getNormal()->anadir(p);
                   this->setNn( this->getNn() + 1);
                }
             //caras      ej orden = (1,nv+1,nv+2,2)
               for (int i= 1; i <= np; i++){
                    c1 = new Cara();
                    c1->setNv(3) ;
                    v = new VerticeNormal(i+(j*np),i+(j*np));
                    c1->getVn()->anadir(v);
                    v = new VerticeNormal(i+np+(j*np),i+(j*np));
                    c1->getVn()->anadir(v);
                    v = new VerticeNormal(((i%np)+1)+np+(j*np),i+(j*np));
                    c1->getVn()->anadir(v);


                    c2 = new Cara();
                    c2->setNv(3) ;
                    v = new VerticeNormal(i+(j*np),i+(j*np));
                    c2->getVn()->anadir(v);
                    v = new VerticeNormal(((i%np)+1)+np+(j*np),i+(j*np));
                    c2->getVn()->anadir(v);
                    v = new VerticeNormal((i%np)+1+(j*np),i+(j*np));
                    c2->getVn()->anadir(v);

                    this->getCara()->anadir(c1);
                    this->setNc( this->getNc() + 1);
                    this->getCara()->anadir(c2);
                    this->setNc( this->getNc() + 1);
                }
         }
}

void CirculoEspiral::Dibuja(){
        

        
        for (int i = 1; i <=this->getNc(); i++){
                glColor3f(1,1,0.5);

                glBegin(GL_LINE_LOOP);
//               glBegin(GL_POLYGON);
                int numero = this->getCara()->dameDato(i)->getNv();
                for (int j = 1; j <= numero; j++){
                        int iv = this->getCara()->dameDato(i)->getIv(j);
                        int in = this->getCara()->dameDato(i)->getIn(j);
                        glNormal3f(this->getNormal()->dameDato(in)->getX(),
                                this->getNormal()->dameDato(in)->getY(),
                                this->getNormal()->dameDato(in)->getZ());

                        glVertex3f(this->getVertice()->dameDato(iv)->getX(),
                                this->getVertice()->dameDato(iv)->getY(),
                                this->getVertice()->dameDato(iv)->getZ());
                }

                glEnd();

        }     


        
        
    

 }




